﻿using BibleBase;
using EXCEL_LIB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Util;
using WORD_LIB;

namespace NVI_LIB
{
    public class IndiceDeTemasParser
    {
        WordSession session;
        Bible NVI { get; set; }
        Bible RV { get; set; }


        public IndiceDeTemasParser(string indiceDeTemasPath,
            string mapeoVocabularioTemasBinPath,
            string modifEntradasBinPath,
            Bible nvi, Bible rv,
            Abreviaturas abrev)
        {
            session = new WordSession();
            session.Show();
            session.Open(indiceDeTemasPath);

            NVI = nvi;
            RV = rv;

            Abrev = abrev;
        }

        public void ParseEntries()
        {
            session.Split(IsEntryParagraph);
        }

        public int CountVerses()
        {
            session.Split(IsVerseParagraph);
            return session.sectionsParagraphs.Count;
        }

        public void ParseVerses()
        {
            session.Split(IsVerseParagraph);
        }

        public void ParseExactVerses()
        {
            session.Extract(IsVerseParagraph, GetCharsCount, GetKey, ConvertToFullKey, GetKeyLength);
        }

        public void ReplaceEntries()
        {
            session.ReplaceText(SearchSubstringToReplace, SearchReplacement);
        }

        public void ReplaceVerses()
        {
            session.ReplaceText(SearchVerseToReplace, SearchVerseReplacement);
        }

        public void HighlightVerses()
        {
            session.HighlightText();
        }

        public void Close()
        {
            session.Close();
            session.Quit();
        }

        public static char GuionLargoChar { get { return '–'; } }
        public static string GuionLargoStr { get { return GuionLargoChar.ToString(); } }

        public static bool IsEntryParagraph(string text)
        {
            if (text.Contains(GuionLargoStr))
            {
                var parts = text.Split(new char[] { GuionLargoChar }).ToList();
                var posibleNumero = parts[0];
                int numero;
                if (int.TryParse(posibleNumero, out numero))
                {
                    return true;
                }
            }
            return false;
        }

        private static Abreviaturas Abrev { get; set; }

        public static bool IsVerseParagraph(string text)
        {
            string[] parts = text.Split(new char[] { ' ' });
            if (parts.Length > 0)
            {
                string book = parts[0];
                int num;
                if (int.TryParse(book, out num))
                    book += (" " + parts[1]);
                if (Abrev.IsAbrev(book))
                {
                    return true;
                }
            }

            return false;

            //if (text.Contains(GuionLargoStr))
            //{
            //    var parts = text.Split(new char[] { GuionLargoChar }).ToList();
            //    var posibleNumero = parts[0];
            //    int numero;
            //    if (int.TryParse(posibleNumero, out numero))
            //    {
            //        return true;
            //    }
            //}
            //return false;
        }

        public int GetCharsCount(Tuple<string, int, int> reference)
        {
            return NVI.GetPlainPassage(reference.Item1, reference.Item2, reference.Item3).Length;
        }

        public static Tuple<string, int, int> GetKey(string paragraph)
        {
            string[] parts = paragraph.Split(new char[] { ' ' });
            int partId = 0;
            if (parts.Length > 0)
            {
                string book = parts[partId++];
                int num;
                if (int.TryParse(book, out num))
                    book += (" " + parts[partId++]);
                if (!Abrev.IsAbrev(book))
                    throw new Exception("Must be a book!");
                parts = parts[partId++].Split(new char[] { ':' });
                int chapter = int.Parse(parts[0]);
                int verse = int.Parse(parts[1]);
                return new Tuple<string, int, int>(book, chapter, verse);
            }
            throw new Exception("We have a problem!");
        }

        public static Tuple<string, int, int> ConvertToFullKey(Tuple<string, int, int> key)
        {
            return new Tuple<string, int, int>(Abrev.GetBookName(key.Item1), key.Item2, key.Item3);
        }

        public int GetKeyLength(Tuple<string, int, int> key)
        {
            return string.Format("{0} {1}:{2}", key.Item1, key.Item2, key.Item3).Length;
        }

        public string SearchSubstringToReplace(string text)
        {
            string[] parts = text.Split(new char[] { ',' });
            return parts[0];
        }

        ModificacionesEntradas modifEntradas { get; set; }
        string ModifEntradasXLSPath { get { return @"C:\NVI\Modificaciones entradas (final).xls"; } }
        string ModifEntradasBinPath { get { return @"C:\NVI\BIN\ModifEntradas.bin"; } }

        private void LoadModificacionesEntradas()
        {
            modifEntradas = new ModificacionesEntradas();

            ExcelSession excel = new ExcelSession();
            var ws = excel.Open(ModifEntradasXLSPath);
            Logger.WriteLine("TotalME: {0}", ws.Rows.Count);
            int errors = 0;
            for (int i = 1; i < ws.Rows.Count && errors < 10; i++)
            {
                if (!modifEntradas.Add(ws.Cells[i, 1].Text, ws.Cells[i, 2].Text, ws.Cells[i, 3].Text))
                {
                    Logger.WriteLine("Item ignorado: {0}, {1}, {2}",
                                ws.Cells[i, 1].Text, ws.Cells[i, 2].Text, ws.Cells[i, 3].Text);
                    errors++;
                }
                Logger.WriteLine("ActualME: {0}", i);
            }
            excel.Close();
            excel.Quit();

            modifEntradas.Serialize<ModificacionesEntradas>(ModifEntradasBinPath);
        }

        public string SearchReplacement(string text)
        {
            if (modifEntradas == null)
                LoadModificacionesEntradas();
            string[] parts = text.Split(new char[] { IndiceDeTemasParser.GuionLargoChar });
            int numero = int.Parse(parts[0]);
            string texto = parts[1];

            ModificacionEntrada modificacion = modifEntradas[texto];
            if (modificacion != null)
            {
                return string.Format("{0}{1}{2}", numero, IndiceDeTemasParser.GuionLargoChar, modificacion.TemaRV);
            }
            else
                return null;
        }

        #region

        public string SearchVerseToReplace(string text)
        {
            string[] parts = text.Split(new char[] { ',' });
            return parts[0];
        }

        //Sal 36:8 Se sacian de la abundancia de tu casa; les das a beber de tu río de deleites.

        public string SearchVerseReplacement(string text)
        {
            string[] parts = text.Split(new char[] { ' ' });
            string shortBook = parts[0];
            string bookName = Abrev.GetBookName(shortBook);
            string schandv = parts[1];
            string[] pchandv = schandv.Split(new char[] { ':' });
            int chapter = int.Parse(pchandv[0]);
            int verse = int.Parse(pchandv[1]);
            string plainPassage = text.Replace(string.Format("{0} {1}", shortBook, schandv), "").Trim();

            //TODO: comprobar que el texto a reemplazar sea el correcto
            string passageNVI = NVI.GetPlainPassage(bookName, chapter, verse);
            string passageRV = RV.GetPlainPassage(bookName, chapter, verse);

            return string.Format("{0} {1}:{2} {3}", shortBook, chapter, verse, passageRV);
        }

        #endregion
    }
}
